#include "misc.h"
#include "dataBase/miscStaticDataFunction.h"
#include "TableInterface/upper_table_interface.h"
#include "TableInterface/ems_table_interface.h"
#include "TableInterface/lc_table_interface.h"
#include "TableInterface/hmi_table_interface.h"
#include "TableInterface/param_table_interface.h"
#include "fpga_interface.h"
#include "msg_queue_interface.h"
#include "msg_queue_pid_define.h"
#include "debug.h"
#include "pulse_operate.h"
#include "rated_limit.h"
#include <sys/syscall.h>
#include <stdlib.h>
#include <signal.h>
#include <syslog.h>
#include <sys/msg.h>
#include <sys/types.h>
#include "ieee_1547.h"
#include "table_refresh.h"
#include "net_param.h"
#include "comm_monitor.h"
#include "logInterface.h"
#include "Commom/mutex_interface.h"
#include "allThread.h"
#include <pthread.h>
#include <unistd.h>
#include <sys/syscall.h>


extern key_t errorMsgKey;


static void  Misc_Terminate(int signum);
static int Misc_RegisterSignal(void)
{
    struct sigaction sa;

    sa.sa_handler = Misc_Terminate;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;

    // sigaction(SIGFPE, &sa, NULL);
    // sigaction(SIGILL, &sa, NULL);
    // sigaction(SIGABRT, &sa, NULL);
    // sigaction(SIGSEGV, &sa, NULL);
    sigaction(SIGTERM, &sa, NULL);

    return 0;
}


static int Misc_InitMutex(void)
{
    for(uint8_t mtxId = 0; mtxId < MUTEX_IDX_QTY; mtxId++)
    {
        if(MutexInf_Init(mtxId) != 0)
        {
            PRINT_ERROR();
            return -1;
        }
    }
    
    return 0;
}


static int Misc_DestroyMutex(void)
{
    uint8_t err = 0;

    for(uint8_t mtxId = 0; mtxId < MUTEX_IDX_QTY; mtxId++)
    {
        if(MutexInf_Destroy(mtxId) != 0)
        {
            PRINT_ERROR();
            err++;
        }
    }
    
    return (err != 0 ? -1 : 0);
}


static int Misc_CreateMsgQueue(void)
{
    for(uint8_t projId = MSG_QUEUE_PID_BEGIN; projId < MSG_QUEUE_PID_END; projId++)
    {
        if(MsgQueue_Create(projId) < 0)
        {
            PRINT_ERROR();
            return -1;
        }
    }
    
    return 0;
}


static int Misc_DeleteMsgQueue(void)
{
    uint8_t projId, err = 0;
    int msgId;

    if(MsgQueue_Delete(errorMsgKey) < 0)
    {
        PRINT_ERROR("Delete error");
        err++;
    }

    for(projId = MSG_QUEUE_PID_BEGIN; projId < MSG_QUEUE_PID_END; projId++)
    {
        if(MsgQueue_Get(projId, &msgId) < 0)
        {
            PRINT_ERROR("Get error");
            err++;
        }
        if(MsgQueue_Delete(msgId) < 0)
        {
            PRINT_ERROR("Delete error");
            err++;
        }
    }
    
    return (err != 0 ? -1 : 0);
}


static int Misc_DeleteTimer(void)
{
    int err = 0;

    if(TableRefresh_DeleteTimer() != 0)
    {
        err++;
    }

    if(CommMonitor_DeleteTimer() != 0)
    {
        err++;
    }

    if(Ieee1547_DeleteTimer() != 0)
    {
        err++;
    }

    return 0;
}


#define BUF_LEN 128
#define RECORD_PATH "/root/debug/record.dat"
static void Misc_ClearRecord(void)
{
    system("echo > "RECORD_PATH);
}


static void Misc_RecordThreadId(const char *funcName)
{
    char buf[BUF_LEN] = {0};
    pid_t tid = syscall(SYS_gettid);
    snprintf(buf, BUF_LEN, "echo %lu - %s >> " RECORD_PATH, (long)tid, funcName);
    system(buf);
}


void Misc_InitThread(const char *funcName)
{
    Misc_RecordThreadId(funcName);

    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
}


void Misc_RecordIpc(uint8_t prjId, key_t key, int ipcId)
{
    char buf[BUF_LEN] = {0};
    snprintf(buf, BUF_LEN, "echo %d - key[0x%08X] ipcId[%d] >> " RECORD_PATH, prjId, key, ipcId);
    system(buf);
}


void Misc_RecordWaveIndex(uint32_t index)
{
    char buf[BUF_LEN] = {0};
    snprintf(buf, BUF_LEN, "sed -i \"""s/waveIndex:[0-9]\\+/waveIndex:%d/g""\" " RECORD_PATH, index);
    system(buf);
}


void Misc_RecordElecIndex(uint32_t cnt, uint8_t fsm, int pwr)
{
    char buf[BUF_LEN] = {0};
    snprintf(buf, BUF_LEN, "sed -i \"""s/cnt:[0-9]\\+,fsm:[0-9]\\+,pwr:[0-9]\\+/cnt:%d,fsm:%d,pwr:%d/g""\" " RECORD_PATH, cnt, fsm, pwr);
    system(buf);
}
#undef RECORD_PATH
#undef BUF_LEN


static void Misc_InitTable(void)
{
    ParamTable_Init();
    UpperTable_Init();
    HmiTable_Init();
    EmsTable_Init();
    LcTable_Init();
    // BmsTable_Init();
    // DcdcTable_Init();
    // MiscTable_Init();
}


void Misc_Init(void)
{
    printf("\n");
    openlog("pcs_upper", LOG_PID, LOG_USER);
    syslog(LOG_NOTICE, "Init");
    Misc_RegisterSignal();
    Misc_ClearRecord();
    NetParam_Init();
    Misc_InitMutex();
    Misc_CreateMsgQueue();
    MSD_MiscFileInit();
    FpgaInf_Init();
    Misc_InitTable();
    RatedLimit_Init();
    logInterfaceLogAdd(LOG_CLASS_SPECIAL, LOG_MAINTYPE_SYS_TIP, 0, COM_DATA_TYPE_NONE, NULL);
}


// #include <stdbool.h>
// static bool signalTag = false;
static void  Misc_Terminate(int signum)
{
    // if(signalTag)
    // {
    //     return;
    // }
    // signalTag = true;
    PRINT_DEBUG("Received signal %d", signum);
    AllThread_CancleThread();
    closelog();
    Misc_DestroyMutex();
    Misc_DeleteMsgQueue();
    Misc_DeleteTimer();
    PRINT_DEBUG("Terminated");
}

